/**
 *	Author:     Kevin.du
 *	CreateTime: 2010-8-2-上午10:01:17
 *	ProjectName:51gen
 *	ClassName:  BaseDaoImpl.java
 *
 *	This Class Or Method Create by Kevin.du 
 *
 *	Copyright ownership belongs to Vilii Kevin, shall not be reproduced , 
 *	copied, or used in other ways without permission.
 *	Otherwise Vilii.Kevin will have the right to pursue legal responsibilities. 
 **/
package com.kevin.ssh2jquery.dao;

import java.io.Serializable;
import java.util.Collection;
import java.util.Iterator;
import java.util.List;
import java.util.Map;
import java.util.Set;

import org.hibernate.Criteria;
import org.hibernate.Query;
import org.hibernate.Session;
import org.hibernate.SessionFactory;
import org.hibernate.criterion.CriteriaSpecification;
import org.hibernate.criterion.DetachedCriteria;
import org.hibernate.criterion.Projection;
import org.hibernate.criterion.Projections;
import org.hibernate.impl.CriteriaImpl;
import org.hibernate.transform.ResultTransformer;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.orm.hibernate3.support.HibernateDaoSupport;
import org.springframework.util.Assert;

/**
 * 基础数据库处理信息
 * 
 * @author kevin.du
 */
@SuppressWarnings("unchecked")
public class BaseDaoImpl<T> extends HibernateDaoSupport implements BaseDao {

	protected Logger log = LoggerFactory.getLogger(getClass());

	public boolean delete(Object object) {
		try {
			super.getSession().delete(object);
			return true;
		} catch (Exception e) {
			log.error("执行删除" + object.getClass().getName() + "失败");
			return false;
		}
	}

	public T findByCode(Class cls, Serializable ser) {
		Object obj = null;
		try {
			obj = getHibernateTemplate().get(cls, ser);
		} catch (Exception e) {
			log.error("执行查找" + cls.getName() + "失败");
			return null;
		}
		return (T) obj;
	}

	public List<T> findByDetached(DetachedCriteria dc) {
		List<T> list = null;
		try {
			list = getHibernateTemplate().findByCriteria(dc);
		} catch (Exception e) {
			log.error("执行搜索出现异常" + e.getMessage());
			return null;
		}
		return list;
	}

	public List<T> getResultByCriteria(Criteria cr) {
		return cr.list();
	}

	public List<T> getResultByHql(String hql, Map<String, ?> params) {
		Session session;
		List<T> list = null;
		try {
			session = getSessionObj();
			Query q = session.createQuery(hql);
			Set set = params.keySet();
			for (Iterator iter = set.iterator(); iter.hasNext();) {
				Object element = (Object) iter.next();
				q.setParameter(element.toString(), params.get(element));
			}
			list = q.list();
		} catch (Exception e) {
			log.error("查询HQL语句出现错误");
			e.printStackTrace();
		}
		return list;
	}

	public List<T> getResultByHql(String Hql) {
		Session session = getSessionObj();
		Query q = session.createQuery(Hql);
		return q.list();
	}

	public long getResultSizeByHql(String hql, Map<String, ?> params) {
		Session session = null;
		Long size = 0L;
		try {
			session = getSessionObj();
			Query q = session.createQuery(hql);
			Set set = params.keySet();
			for (Iterator iter = set.iterator(); iter.hasNext();) {
				Object element = (Object) iter.next();
				q.setParameter(element.toString(), params.get(element));
			}
			size = (Long) q.uniqueResult();
		} catch (Exception e) {
			log.error("执行查询总数出现异常");
			e.printStackTrace();
		}

		return size;
	}

	public Object getResultSumByHql(String hql, Map<String, ?> params) {
		Session session = null;
		Object sum = null;
		try {
			session = getSessionObj();
			Query q = session.createQuery(hql);
			Set set = params.keySet();
			for (Iterator iter = set.iterator(); iter.hasNext();) {
				Object element = (Object) iter.next();
				q.setParameter(element.toString(), params.get(element));
			}
			sum = q.uniqueResult();
		} catch (Exception e) {
			e.printStackTrace();
		}
		return sum;
	}

	public Session getSessionObj() {
		return super.getSession();
	}

	public boolean save(Object object) {
		try {
			getHibernateTemplate().save(object);
			return true;
		} catch (Exception e) {
			log.error("插入对象" + object.getClass().getName() + "出现异常");
			e.printStackTrace();
			return false;
		}
	}

	public boolean saveOrUpdate(Object object) {
		try {
			getHibernateTemplate().saveOrUpdate(object);
			return true;
		} catch (Exception e) {
			log.error("保存或更新信息-->" + object.getClass().getName() + "<--出现异常");
			e.printStackTrace();
			return false;
		}
	}

	public boolean saveOrUpdateAll(Collection<Object> coll) {
		try {
			getHibernateTemplate().saveOrUpdateAll(coll);
			return true;
		} catch (Exception e) {
			log.error("批量保存或更新信息出现异常");
			e.printStackTrace();
			return false;
		}
	}

	public boolean update(Object object) {
		try {
			getHibernateTemplate().update(object);
			return true;
		} catch (Exception e) {
			log.error("更新信息-->" + object.getClass().getName() + "<--出现异常");
			e.printStackTrace();
			return false;
		}
	}

	/**
	 * 构建Query 语句
	 * 
	 * @param queryString
	 * @param values
	 * @return
	 */
	public Query createQuery(final String queryString, final Object... values) {
		Assert.hasText(queryString, "queryString不能为空");
		Query query = getSession().createQuery(queryString);
		if (values != null) {
			for (int i = 0; i < values.length; i++) {
				query.setParameter(i, values[i]);
			}
		}
		return query;
	}

	@Autowired
	public void setSessionFactoryTemp(SessionFactory sessionFactory) {
		super.setSessionFactory(sessionFactory);
	}

	/**
	 * 执行count查询获得本次Criteria查询所能获得的对象总数.
	 */
	protected int countCriteriaResult(final Criteria c) {
		CriteriaImpl impl = (CriteriaImpl) c;

		// 先把Projection、ResultTransformer,清空二者后再执行Count操作
		Projection projection = impl.getProjection();
		ResultTransformer transformer = impl.getResultTransformer();

		// 执行Count查询
		int totalCount = (Integer) c.setProjection(Projections.rowCount())
				.uniqueResult();

		// 将之前的Projection,ResultTransformer条件重新设回去
		c.setProjection(projection);

		if (projection == null) {
			c.setResultTransformer(CriteriaSpecification.ROOT_ENTITY);
		}
		if (transformer != null) {
			c.setResultTransformer(transformer);
		}
		return totalCount;
	}

}
